<?php
/* 
    contactform - html form mail contact for joomla! 1.5
    Copyright (C) 2009  Trigallez Arno

    This file is part of contactform.

    contactform is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    contactform is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with contactform.  If not, see <http://www.gnu.org/licenses/>.
*/

// no direct access
defined('_JEXEC') or die('Restricted access');
jimport( 'joomla.mail.helper' ); // getMailer joomla method
jimport('joomla.utilities.date');

class modcontactformHelper
{
	var $subject = NULL; // mail subject
	var $recipient1 = NULL; // 1 mail destination
	var $recipient2 = NULL; // 2 mail destination
	var $recipient3 = NULL; // 3 mail destination
	
	var $error_message = NULL;
	var $succes_message = NULL;
	var $session_message = NULL;
	
	var $phoneMustBe = false; // set if phone is optionnal  or not
	var $token = false; // token activate
	var $token_session = 10;
	
	var $phone =  NULL;
	var $adress =  NULL;
	var $fromemail  =  NULL;
	var $name =  NULL;
	var $msg = NULL;
	var $succes = false;
	
	var $token_token = false;
	var $token_name = false;

	/* Public methods */
	
	// contructor - use it give params to the objet
	function init(&$params)
	{
		$this->subject = $params->get("to_subject"); // mail subject
		$this->recipient1 = $params->get("to_email"); // 1 mail destination
		$this->recipient2 = $params->get("to_email2"); // 2 mail destination
		$this->recipient3 = $params->get("to_email3"); // 3 mail destination
		$this->phoneMustBe = $params->get("phone_require"); // set if phone is optionnal  or not
		$this->token = $params->get("token_activate"); // set if phone is optionnal  or not
		$this->token_session = $params->get("token_session"); // session time duration
		
		// token protection is activate ?
		if($this->token)
		{
			// add-in SQL token table if it don't exists
			$db =& JFactory::getDBO();
			$query = "CREATE TABLE IF NOT EXISTS `#__contactform_token`(
				`id` integer unsigned NOT NULL default NULL auto_increment,
				`name` varchar(255) NOT NULL,
				`token` varchar(255) NOT NULL,
				`dateCreate` datetime NOT NULL,
				PRIMARY KEY(`id`)
			)CHARACTER SET `utf8` COLLATE `utf8_general_ci`;";
			$db->setQuery($query);
			$db->query();
			
			
			// clean expirate tokens
			$mydate = gmdate("M d Y H:i:s", time() - $this->token_session * 60); // now - x minute
			$dateNow = new JDate($mydate);
			modcontactformHelper::_delExpirateToken($dateNow->toMySQL());
		}
	}

	
	// check if form is complet
	function check() // return bool
	{
		$this->phone =  JRequest::getVar( 'phone', NULL, 'post', 'string');
		$this->adress =  JRequest::getVar( 'adress', NULL, 'post', 'string');
		$this->fromemail  =  JRequest::getVar( 'fromemail', NULL, 'post', 'string');
		$this->name =  JRequest::getVar( 'name', NULL, 'post', 'string');
		
		$this->msg = JRequest::getVar( 'message', NULL, 'post', 'string');
		
		// all field * are fill ?  address e-mail valid ?
		if(!empty($this->msg) && !empty($this->fromemail) && !empty($this->name) 
			&& JMailHelper::isEmailAddress($this->fromemail)&& ($this->token == false or modcontactformHelper::_checkTokens() == true))
		{
			// phone is require and give ? is't a real phone number ?
			if($this->phoneMustBe == false || ( !empty($this->phone) && modcontactformHelper::_isPhoneNumber($this->phone)))
			{
				$this->succes = true;
				$this->message = $this->succes_message;
				return true;
			}
			else
			{
				$this->succes = false;
				$this->message = $this->error_message;
				return false;
			}
		}
		else
		{
			$this->succes = false;

			// all field complete so it is a token error
			if(!empty($this->msg) && !empty($this->fromemail) && !empty($this->name) && JMailHelper::isEmailAddress($this->fromemail))
				$this->message = $this->session_message;
			else
				$this->message = $this->error_message;
				
			return false;
		}
	}
	
	// send the e-mail !
	function send() // return  bool
	{
		$result = false;
	
		// remove space from phone number (keep only num char)
		$phonenumber = modcontactformHelper::_escapePhoneNumber($this->phone); 
		
		$body = "
Name: $this->name
E-mail: $this->fromemail
Tel: $phonenumber
Address: $this->adress 

Message:

$this->msg";

		$mailer =& JFactory::getMailer();
		$mailer->setSender($this->fromemail);
		$mailer->setSubject($this->subject);
		$mailer->addRecipient($this->recipient1);
			
		$mailer->setBody($body);
		$mailer->IsHTML(false);
		if($mailer->Send() !== true)
		{
			// error
			// TODO : put something here
		}
		else
			$result = true;

		// make a copy to second address 
		if(!empty($this->recipient2))
		{
			$mail2 =& JFactory::getMailer();
			$mail2->setSender($this->fromemail);
			$mail2->setSubject($this->subject);
			$mail2->addRecipient($this->recipient2);
			
			$mail2->setBody($body);
			$mail2->IsHTML(false);
			$mail2->Send();
		}
		// make a copy to 3st address 
		if(!empty($this->recipient3))
		{
			$mail3 =& JFactory::getMailer();
			$mail3->setSender($this->fromemail);
			$mail3->setSubject($this->subject);
			$mail3->addRecipient($this->recipient3);
			
			$mail3->setBody($body);
			$mail3->IsHTML(false);
			$mail3->Send();
		}
		
		return $result;
	}
	

	function setErrorMessage($message) // no return
	{
		$this->error_message = $message;
	}
	
	function setSuccesMessage($message) // no return
	{
		$this->succes_message = $message;
	}
	
	function setSessionMessage($message) // no return
	{
		$this->session_message = $message;
	}
	
	// show the form
	function display() // no return
	{
		if(modcontactformHelper::_isSending())
		{
			if(modcontactformHelper::check())
				modcontactformHelper::send();
			
			if($this->token)
				modcontactformHelper::_generateToken(); // generate and add-in a new token

			modcontactformHelper::_getFrom($this->message, $this->token_name, $this->token_token);
		}
		else
		{
			if($this->token)
				modcontactformHelper::_generateToken(); // generate and add-in a new token

			modcontactformHelper::_getEmptyForm($this->token_name, $this->token_token);
			
		}	
	}
	
	
	/* Private methods */
	
	// check if $presumePhone is a phone number
	function _isPhoneNumber(/* string */ $presumePhone ) // return bool
	{
		if(preg_match("/[a-z]/i", $presumePhone))
			return false;
	
		if(!preg_match("/[0-9]/i", $presumePhone))
			return false;
	
		if(strlen($presumePhone ) < 6)
			return false;
			
		return true;
	}

	// Only keep numeric char. Also change +prefix to 00prefix
	// ex: +32 06 89 30 58 90  become  00320689305890
	function _escapePhoneNumber(/* string */ $number) // return string
	{
		if(is_string($number))
		{
			if($number[0] == '+')
				$number = "00" .$number;
			
			$number = ereg_replace("[^0-9]","",$number);
		}	
		return $number;
	}
	
	// generate an unique url
	function _uniqueLink($url) // return string
	{
		// make unique form url to avoir cache problem
		$datepub = date("r" ); 
		$lien=date("y"."m"."d"."H"."i"."s" );
		
		
		// add unique url
		if(strpos($url, "?") === false)
			$url = $url . "?task=send";
		else
		    $url = $url . "&task=send";
			
		return $url.$lien;
	}

	// check if user is sending or just get the form
	function _isSending() // return bool
	{
		if(JRequest::getVar( 'send', NULL, 'post', 'string') == "contactform")
			return true;
		else
			return false;
	}
	
	// echo the form with field type by user
	function _getFrom($message, /* string */ $tokenName = false, /* string */ $token = false) // no return
	{
		// get current url
		$u =& JFactory::getURI();
		$url = $u->toString();
		// from's action unique url
		$action = modcontactformHelper::_uniqueLink($url); //to avoid cache problem
	
	?>
	<div class="container-contactform">
		<form method="post" action="<?php echo $action; ?>">
			<input type="hidden" name="send" value="contactform"/>
						<?php 
			if(tokenName == true && $token == true)
				echo '<input type="hidden" name="' . $tokenName . '" value="' . $token.'"/>';
			?>
			<table width="100%" cellpadding="0" cellspacing="0">
			<tr>
				<td width="50%">
					<?php echo JText::_('OUR_NAME'); ?> <span class="asterix<?php if(empty($this->name)) echo "-error"; ?>">*</span><br/>
					<input name="name" size="30" value="<?php if(!empty($this->name) && $this->succes == false) echo $this->name; ?>" /><br/>
				</td>
				<td width="50%">
					<?php echo JText::_('ADDRESS_EMAIL'); ?> <span class="asterix<?php if(empty($this->fromemail) || !JMailHelper::isEmailAddress($this->fromemail)) echo "-error"; ?>">*</span><br/>
					<input name="fromemail" size="30" value="<?php if((!empty($this->fromemail) && $this->succes == false) && JMailHelper::isEmailAddress($this->fromemail)) echo $this->fromemail; ?>" /><br/>
				</td>
			</tr>
			<tr>
				<td width="50%">
					<?php echo JText::_('TELEPHONE'); ?> 
					<?php if($this->phoneMustBe == true) 
					{ 
					?>
					<span class="asterix<?php if(empty($this->phone) || !modcontactformHelper::_isPhoneNumber($this->phone)) echo "-error"; ?>">*</span>
					<?php 
					} 
					?>
					<br/>
					<input name="phone" size="30" value="<?php if((!empty($this->phone) && $this->succes == false) && modcontactformHelper::_isPhoneNumber($this->phone)) echo $this->phone; ?>" /><br/>
				</td>
				<td width="50%">
					<?php echo JText::_('ADDRESS'); ?><br/>
					<input name="adress" size="30" value="<?php if(!empty($this->adress) && $this->succes == false) echo $this->adress; ?>" /><br/>
				</td>
			</tr>
			</table>
			<table width="100%" cellpadding="0" cellspacing="0">
				<tr>
					<td>
						<?php echo JText::_('OUR_MESSAGE'); ?> <span class="asterix<?php if(empty($this->msg)) echo "-error"; ?>">*</span><br/>
						<textarea name="message" cols="50" rows="6" style="width: 420px;"><?php if(!empty($this->msg) && $this->succes == false) echo $this->msg; ?></textarea><br />
					</td>
				</tr>
			</table>
		
				<table width="100%" cellpadding="0" cellspacing="0" class="table-envoyer-contact">
					<tr>
						<td class="td-envoyer-contact">
							<input type="submit" value="<?php echo JText::_('SEND'); ?>"/>
						</td>
						<td class="td-message-contact">
							<center><?php echo $message; ?></center>
						</td>
					</tr>
				</table>
		</form>
	</div>
	<?php
	}
	
	// echo the form
	function _getEmptyForm(/* string */ $tokenName = false, /* string */ $token = false) // no return
	{
		// get current url
		$u =& JFactory::getURI();
		$url = $u->toString();
		// from's action unique url
		$action = modcontactformHelper::_uniqueLink($url); //to avoid cache problem
	?>
	<div class="container-contactform">
		<form method="post" action="<?php echo $action; ?>">
			<input type="hidden" name="send" value="contactform"/>
			<?php 
			if(tokenName == true && $token == true)
				echo '<input type="hidden" name="' . $tokenName . '" value="' . $token.'"/>';
			?>
			<table width="100%" cellpadding="0" cellspacing="0">
			<tr>
				<td width="50%">
					<?php echo JText::_('OUR_NAME'); ?> <span class="asterix">*</span><br/>
					<input name="name" size="30" /><br/>
				</td>
				<td width="50%">
					<?php echo JText::_('ADDRESS_EMAIL'); ?> <span class="asterix">*</span><br/>
					<input name="fromemail" size="30"/><br/>
				</td>
			</tr>
			<tr>
				<td width="50%">
					<?php echo JText::_('TELEPHONE'); ?> 
					<?php if($this->phoneMustBe == true) 
					{ 
					?>
					<span class="asterix">*</span>
					<?php
					}
					?>
					<br/>
					<input name="phone" size="30"/><br/>
				</td>
				<td width="50%">
					<?php echo JText::_('ADDRESS'); ?> <br/>
					<input name="adress" size="30"/><br/>
				</td>
			</tr>
			</table>
			<table cellpadding="0" cellspacing="0">
				<tr>
					<td>
						<?php echo JText::_('OUR_MESSAGE'); ?> <span class="asterix">*</span><br/>
						<textarea name="message" cols="50" rows="6"></textarea><br/>
					</td>
				</tr>
			</table>
			<table width="100%" cellpadding="0" cellspacing="0" class="table-envoyer-contact">
				<tr>
					<td class="td-envoyersolo-contact">
						<input type="submit" value="<?php echo JText::_('SEND'); ?>"/>
					</td>
				</tr>
			</table>
		</form>
	</div>
	<?php
	}
	
	// generate a random string
	function _getRandString($length = 10, 
		$letters = '1234567890qwertyuiopasdfghjklzxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZ') // return string
	{
		$s = '';
		$lettersLength = strlen($letters)-1;
     
		for($i = 0 ; $i < $length ; $i++)
		{
			$s .= $letters[rand(0,$lettersLength)];
		}
		
		return $s;
	} 
	
	
	// generate a random string
	function _newToken($name, $token, $date) // no return
	{
		$db =& JFactory::getDBO();
		$query = "INSERT INTO `#__contactform_token` (
`id` ,
`name` ,
`token` ,
`dateCreate`
)
VALUES (
NULL , ". $db->Quote($name) .", ". $db->Quote($token) .", ". $db->Quote($date) ."
);";
		$db->setQuery($query);
		$db->query();
	} 
	
	// generate a new token and it to DataBase
	function _generateToken() // no return
	{
		// add-in a new token
		$this->token_name =  modcontactformHelper::_getRandString(15);
		$this->token_token = modcontactformHelper::_getRandString(15);
			
		$mydate = gmdate("M d Y H:i:s", time() - 60); // now - 1 minute
		$dateNow = new JDate($mydate);
			
		modcontactformHelper::_newToken($this->token_name, $this->token_token, $dateNow->toMySQL());
	}
	
	function _delExpirateToken($time) // no return
	{
		$db =& JFactory::getDBO();
		$query = "DELETE FROM `#__contactform_token` WHERE dateCreate <= ". $db->Quote($time) .";";
		$db->setQuery($query);
		$db->query();
	}
	
	function _delToken(/*string */ $name, /*string */ $token)
	{
		$db =& JFactory::getDBO();
		$query = "DELETE FROM `#__contactform_token` WHERE name = ". $db->Quote($name) . " and token = " . $db->Quote($token) . " ;";
		$db->setQuery($query);
		$db->query();
	}
	
	// return all non expirate token name
	function _getValidTokenNameList(/*MySQL datetime */ $begintime) // return array 
	{
		$db =& JFactory::getDBO();
		$query = "select name FROM `#__contactform_token` WHERE dateCreate > ". $db->Quote($begintime) ." ;";
		$db->setQuery($query);
		
		return $db->loadObjectList();
	}
	
	// get token by token name
	function _getToken($tokenname) // return array
	{
		$db =& JFactory::getDBO();
		$query = "SELECT token FROM `#__contactform_token` WHERE name = " . $db->Quote($tokenname) .";";
		$db->setQuery($query);
		
		return $db->loadObjectList();
	}
	
	// check if token pass in post is correct
	function _checkTokens() // return bool
	{
		$mydate = gmdate("M d Y H:i:s", time() - ($this->token_session * 60) + 60); // x minute ago
		$dateExpiration = new JDate($mydate);
			
		$list = modcontactformHelper::_getValidTokenNameList($dateExpiration->toMySQL());

		if(count($list) > 0) // check list is correct
		{
			for($i = 0; $i < count($list); $i++) // for all valid token name
			{
				if(array_key_exists($list[$i]->name , $_POST)) // check if post array, got this token name
				{
					$tokenList = modcontactformHelper::_getToken($list[$i]->name); // token name is not unique could return more that one !
					$token = JRequest::getVar( $list[$i]->name, NULL, 'post', 'string' );
					
					if(count($tokenList) > 0) // check list is correct
					{
						// user token match with valid token ?
						for($e = 0; $e < count($tokenList); $e++)
						{
							if($token == $tokenList[$e]->token)
							{
								// remove this token from data base, only one usage
								modcontactformHelper::_delToken($list[$i]->name, $token);
								return true; // ok token is valid
							}
						}
					}
				}
			}
		}
		return false;
	}

}






